package OBSXML;

import Databasehandler.DBConnector;
import Databasehandler.MySQLCommunicator;
import Errorhandler.ErrorLogger;
import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 * Henter rapport og skriver dem til database.
 *
 * @author Børge
 */
public class ReportCollector{
    /*
     * 1. hent reportDir i Fileobject - REPORTFINDER
     * 2. find alle rapporter i reportDir - REPORTFINDER
     * 3. Validér rapport - XMLVALIDATOR
     * 4. hvis rapport er validt, hent report og detaljesæt
     *  4.a. hvis rapport ikke er validt, skriv rapportnavn og fejlmeddelse til errorlog og flyt fil til errorValidated mappen
     * 5. skriv valid rapport til database, og returnerer rapportens id
     * 6. skriv hvert detaljesæt til database med tilknytning til rapportens id
     */

    
    private String parent = System.getProperty("user.dir");
    private final String xsd = parent + File.separator + "tools" + File.separator + "BatchSummary.xsd";
    private int batchReportSystemID = 0;

    private String logDir = parent + File.separator+"log"+File.separator;
    private String logName = "ReportCollectorErrors.log";
    
    private LinkedList<String> validReports = new LinkedList<String>();
    private LinkedList<String> nonValidReports = new LinkedList<String>();
    private ReportFinder rf;
    private XMLValidator xv = new XMLValidator();

    /**
     * Ved start valideres xml, og ligges i en valid eller ikke-valid liste
     */
    public ReportCollector()
    {
        
        rf = new ReportFinder();
        LinkedList<String> reports = rf.getFileList();

        for(String s : reports)
        {
            if(xv.XMLValidator(s, xsd))
                validReports.add(s);
            else
                nonValidReports.add(s);
        }
    }

    /**
     * Laver et Arraylist af ArrayList med String type af rapporter og tilhørende
     * detaljesæt.
     *
     * @return ArrayList<ArrayList<String>>
     */
    private ArrayList<ArrayList<String>> readReport()
    {
        String path = null;
        String xmlFile = null;
        XML x = null;
        ArrayList<String> rr = null;
        ArrayList<String> rd = null;
        ArrayList<ArrayList<String>> rrDetailset = new ArrayList<ArrayList<String>>();

        int counter = 0;
        for(String s : validReports)
        {
            path = s.substring(System.getProperty("user.dir").length()+1, s.lastIndexOf(File.separator));
            xmlFile = s.substring(s.lastIndexOf(File.separator)+1);

            x = new XML(path, xmlFile);

            //Tilføj rapportsværdier
            rr = x.readXMLParentValues();
            rrDetailset.add(counter, rr);
            counter++;
            //Tilføj detaljesæt for rapport
            rd = x.readDetailSetValues();
            rrDetailset.add(counter, rd);

            counter++;
        }
        return rrDetailset;
    }

    /**
     * Skriver rapporter og detaljesæt i databasen
     */
    public void writeReportToDB()
    {
        try {
            DBConnector dbc = new DBConnector();
            MySQLCommunicator msc = new MySQLCommunicator(dbc);
            //Indhent batchreportsystemid
            
            
            //Skriv rapport til database og returnerer den nye rapports id
            //Itererer gennem antal rapporter
            ArrayList<ArrayList<String>> rrTemp = readReport();
            for(int i = 0; i<rrTemp.size();i+=2)
            {
                ArrayList<String> temp = rrTemp.get(i);

                //Itererer gennem hver rapport
                for(int j = 0; j<temp.size(); j=+6)
                {
                    int id = msc.getBatchReportSystemID(temp.get(0));
                    msc.createBatchReport(id, temp.get(1), temp.get(2).replace('T', ' '), temp.get(3).replace('T', ' '), Boolean.parseBoolean(temp.get(4)), temp.get(5));

                    
                }
                //Skriver hvert detaljesæt i db med rapport id

                ArrayList<String> temp1 = rrTemp.get(i+1);
                for(int l = 0; l<temp1.size();l+=6)
                {
                    msc.createBatchReportDetailSet(getNewReportsID(), temp1.get(0+l),Integer.parseInt(temp1.get(1+l)),Integer.parseInt(temp1.get(2+l)),Integer.parseInt(temp1.get(3+l)),Integer.parseInt(temp1.get(4+l)),Integer.parseInt(temp1.get(5+l)));

                }
            }
            
            
        } catch (SQLException ex) {
            try {
                ErrorLogger.writeToErrorLog(logDir+logName,"SQL FEJL: "+ex.getMessage()+"\n");
            } catch (Exception ex1){} // fejl hvis der ikke kan skrives til log kan ikke håndteres, SKRIV_TIL_OS_EVENT_LOG
        }
        moveValidLoadedFiles();
    }

    /**
     * Returnerer en ny rapports ID
     *
     * @return int
     */
    private int getNewReportsID()
    {
        DBConnector dbc = new DBConnector();
        int batchReportID = 0;
        try {
            Statement stmt = dbc.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT BatchReportID FROM tbl_batchreport ORDER BY BatchReportID DESC LIMIT 1");

            while (rs.next()) {
                batchReportID = rs.getInt(1);
            }
            dbc.closeConn();

        } catch (SQLException ex) {
            try {
                ErrorLogger.writeToErrorLog(logDir+logName,"SQL FEJL: "+ex.getMessage()+"\n");
            } catch (Exception ex1){} // fejl hvis der ikke kan skrives til log kan ikke håndteres, SKRIV_TIL_OS_EVENT_LOG
        }
        return batchReportID;
    }

    /**
     * Gør klar til at flytte valide filer til mappen loadedfiles
     */
    private void moveValidLoadedFiles()
    {
        for(String s : validReports)
        {
            fileMover(s, "reports", "loadedfiles");
        }
    }

    /**
     * Flytter filer i mappe
     */
    private void fileMover(String oldFile, String reportDir, String folder)
    {
        File f = new File(oldFile);
        f.renameTo(new File(parent+File.separator+reportDir+File.separator+folder+File.separator+oldFile.substring(oldFile.lastIndexOf(File.separator))));
        f.delete();
    }
}
